package com.example.mykotlinapp

import java.lang.StringBuilder

/**
 *
 * 第八章  高阶函数
 * @author zhudeshuai
 * @since 2019/7/18
 */


//函数类型
//val sum = {x:Int,y:Int -> x + y}
val sum: (Int, Int) -> Int = { x, y -> x + y }
val action: () -> Unit = { println(24) }

//调用作为参数的函数

fun twoAndThree(operation: (Int, Int) -> Int) {
    val result = operation(2, 3)
    println("The result is $result")
}

private fun test140() {
    twoAndThree { a, b ->
        a + b
    }

    twoAndThree(operation = { x, y -> x * y })
}


fun String.filter(predicate: (Char) -> Boolean): String {
    val sb = StringBuilder()
    for (index in 0 until length) {
        val char = get(index)
        if (predicate(char)) {
            sb.append(char)
        }
    }
    return sb.toString()
}

private fun test141() {
    println("abcxyz".filter { it in 'a'..'c' })
}

//函数参数的默认值
private fun <T> Collection<T>.joinToString(
    separator: String = ",",
    prefix: String = "",
    postfix: String = "",
    transform: (T) -> String = { it.toString() }
): String {
    val result = StringBuilder(prefix)
    for ((index, element) in this.withIndex()) {
        if (index > 0) result.append(separator)
        result.append(transform(element))
    }
    result.append(postfix)
    return result.toString()
}

private fun test142() {
    val list = listOf("Jack", "Tom", "Bob")
    println(list.joinToString(";", ":", "...") { it.toUpperCase() })
}


//使用函数类型的可空参数
private fun <T> Collection<T>.joinToStringOrNull(
    separator: String = ",",
    prefix: String = "",
    postfix: String = "",
    transform: ((T) -> String)? = null
): String {
    val result = StringBuilder(prefix)
    for ((index, element) in this.withIndex()) {
        if (index > 0) result.append(separator)
        result.append(transform?.invoke(element) ?: element.toString())
    }
    result.append(postfix)
    return result.toString()
}


//返回函数的函数

enum class VipLevel {
    ONE, TWO
}

//根据会员等级返回计算价格方式
private fun getNeedPayPrice(level: VipLevel): (Double) -> Double {
    if (level == VipLevel.ONE) {
        return { originPrice -> 0.85 * originPrice - 10 }
    }
    return { originPrice -> 0.95 * originPrice }
}

private fun test143() {
    println(getNeedPayPrice(VipLevel.TWO)(200.0))
}


private fun main() {
}